import axios from 'axios'
import Vue from 'vue'
import { http } from '@/config.js'
import store from '@/store/index.js'
var reqIndex = 0; // 请求测试


// 请求地址配置
axios.defaults.baseURL = http


// 添加请求拦截器
// 在发送请求之前做些什么 c => config 参数
// loading: true 需要显示loading层
// sign: true 需要加入签名认证
// hidemsg: true 不提示错误消息
// retry: true 表示重试，刷新token后的再次请求
axios.interceptors.request.use((c) => {
    // 请求头Authorization
    c.headers.Authorization = 'Bearer ' + localStorage.token;
    return c;
}, function (error) {
    // Do something with request error
    return Promise.reject(error);
});


// 响应拦截器
axios.interceptors.response.use(response => {
    if (response.config.loading) {
        // 关闭loading 
        console.log("__关闭loading_")
    }

    // 请求成功
    if (response.status && response.status == 200) { // 表示请求成功
        let { code, msg } = response.data; // 请求返回的数据，约定必须包含 code 和 msg
        if (code && code != 0) {
            if (msg == "token无效") {
                console.log("__进入token无效判定，清除缓存__")

                store.commit('mtLogout'); // 清除vuex的状态 
            }
            if (response.config.loading) {
                // 如果有show, 这里就关闭loading 
                console.log("__关闭loading_")
            }
            if (!response.config.hidemsg) { // 如果没有隐藏消息, 则同意显示错误消息
                console.log("__弹框报错_");
            }
        }
        return response.data;
    }
    // ****** 以下是请求失败执行 ******
    let bFlag = false;
    let sErrMsg = '';
    if (response.errMsg) sErrMsg = response.errMsg;
    if (sErrMsg == 'request:fail') {
        //  请求数据类型错误 / 请求不存在的地址 / 服务器关闭 / api请求500错误 / 没有网络
        bFlag = true;
        response.data = {
            code: -10000,
            msg: '请求失败!',
        };
    }
    if (sErrMsg.indexOf('timeout') != -1) { // request:fail timeout
        //  请求超时，一般是超过1分钟
        bFlag = true;
        response.data = {
            code: -10001,
            msg: '请求超时!',
        };
    }
    if (!bFlag) {
        // 其他失败
        response.data = {
            code: -10009,
            msg: '网络异常！',
        };
    }

    console.log("__弹框组件报错_");
    throw new Error(response.data.msg);

}, async err => {
    // console.log(`[${reqIndex}]请求返回, type = ${typeof err}, err = `,err)	//[测试]
    // 第一次进入, err 对象包含 config,response,isAxiosError,toJSON 
    // 其中 response 包含 errMsg,status,config
    if (err.response && err.response.errMsg == 'request:ok' && err.response.status == 401) {
        // console.log(`[${reqIndex}]没有权限-----------------`, err.config);
        // 判断是否需要再次请求
        let retry, hidemsg, sign;
        if (err.config.retry) retry = err.config.retry;
        if (err.config.hidemsg) hidemsg = err.config.hidemsg;
        if (err.config.sign) sign = err.config.sign;
        let bAgain = sign && !retry;
        // console.log(`[${reqIndex}]bAgain = `, bAgain);  // 是否再次请求
        // 如果不需要再次请求，则返回结果
        if (!bAgain) {
            console.log("进入1")
            if (err.response.config.loading) {
                // 关闭loading 
                console.log("__关闭loading_")
            }
            err.response.data = {
                code: -401,
                msg: '没有权限',
                res_data: '请重新登录'
            };

            return err.response;
        }
        // 再次请求
        let refresh_token = store.state.userInfo.refresh_token;
        if (!refresh_token) {  // token是空的 重新登录
            if (err.response.config.loading) {
                // 关闭loading 
                console.log("__关闭loading_")
            }
            err.response.data = {
                code: -401,
                msg: '没有权限',
                res_data: 'token是空的 请重新登录'
            };

            console.log("__弹框组件报错_ 未通过安全策略 请检查网络环境");

            store.commit('mtLogout'); // 清除vuex的状态 
            return err.response;
        }
        // 刷新token
        let { method, url, data } = err.config;
        let refresh_res = await axios({
            method: 'POST',
            url: 'Authentication/Refresh',
            data: { RefreshToken: refresh_token },
            retry: true, //重试
            hidemsg: true, // 不显示消息提示 
        })
        // console.log(`[${reqIndex}]再次请求结果 refresh_res.data  = `, refresh_res.data);  // [测试]

        let { code, msg } = refresh_res.data;
        if (code != 0) { // 刷新失败，删除token 
            if (err.response.config.loading) {
                // 关闭loading 
                console.log("__关闭loading_")
            }
            store.commit('mtLogout'); // 清除vuex的状态 
            refresh_res.data.code = -401; // 设置 -401 重新登录
            return refresh_res; // 之前已经响应过，直接传出去 
        }


        // 刷新成功，保存token, 继续请求
        store.commit('mtRefreshToken', refresh_res.data); // 保存到vuex 
        if (data) data = JSON.parse(data); // (如有参数)这里需要把 string 转化成JSON对象 重新请求 
        return await axios({
            method,
            url,
            data,
            sign: true,
            retry: true, //重试
            hidemsg,
        });

    }
    // ****** 以下是请求失败执行 ******
	let sErr = err.toString() 
	if(sErr.indexOf('Invalid URL') != -1) { 
		err.response = {
			data:{
				code: -404,
				msg: '请求地址无效', 
			}
		} 
	}else{
		err.response = {
			data:{
				code: -409,
				msg: '网络连接异常，请重新登录', 
			}
		}  
	}
    return err.response;  
})

export default axios